package xcmg.syn.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author wangyong
 */
public class TaskUtils {

  static long sum = 0;

  /**
   * TODO 可能要参考服务器配置重新优化下线程池参数
   * 将任务分为多个list并行执行
   *
   * @param list 任务列表
   * @param obj method所在类的实例, 第一个参数为List，第二个参数为Map
   * @param paramMap method所需参数，在调用处放入map中，在method中get出来
   * @param method 要执行的方法
   * @param threadCounts 线程数
   */
  public static void excuteTask(List list, Object obj, Map paramMap, Method method,
      int threadCounts)
      throws Exception {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCounts, 10, 10,
        TimeUnit.SECONDS, new ArrayBlockingQueue<>(1024));
//    exec.setThreadFactory();

    List<Callable<Long>> callList = new ArrayList<>();
    int len = list.size() / threadCounts;
    //List.size() < 线程数的情况
    if (len == 0) {
      threadCounts = list.size();
      len = list.size() / threadCounts;
    }
    for (int i = 0; i < threadCounts; i++) {
      // 需要处理的数据分为多块并行处理
      final List subList;
      if (i == threadCounts - 1) {
        subList = list.subList(i * len, list.size());
      } else {
        subList = list.subList(i * len, len * (i + 1) > list.size() ? list.size() : len * (i + 1));
      }
      callList.add(() -> {
        long subSum = 0L;
        method.invoke(obj, subList, paramMap);
        return subSum;
      });
    }
    List<Future<Long>> futureList = executor.invokeAll(callList);
    for (Future<Long> future : futureList) {
      sum += future.get();
    }
    executor.shutdown();
  }
}